#ifndef DUALCIRCLELISTV2_H
#define DUALCIRCLELISTV2_H

#include "DualLinkList.h"

namespace DSLib
{

	template <typename T>
	class DualCircleListV2 : public DualLinkList<T>
	{
	protected:
		typedef typename DualLinkList<T>::Node Node;

		int mod(int i) const
		{
			return (this->m_length == 0) ? 0 : (i % this->m_length);
		}

		Node* last() const
		{2
			return this->position(this->m_length - 1)->next;
		}

		void last_to_first()
		{
			Node* first = this->position(0)->next;

			last()->next = first;
			first->pre = last();
		}
	public:
		virtual bool insert(int i, const T& e)
		{
			bool ret = true;

			i = i % (this->m_length + 1);
			ret = DualLinkList<T>::insert(i, e);

			if (ret && (i == 0))
			{
				last_to_first();
			}

			return ret;
		}

		virtual bool insert(const T& e)
		{
			return insert(this->m_length, e);
		}

		virtual bool remove(int i)
		{
			bool ret = true;

			i = mod(i);

			if (i == 0)
			{
				Node* toDel = this->position(i)->next;
				if (toDel != NULL)
				{
					Node* next = toDel->next;

					this->m_header.next = next;
					next->pre = toDel->pre;

					this->m_length--;

					if (this->m_length > 0)
					{
						last_to_first();

						if (this->m_current == toDel)
						{
							this->m_current = toDel->next;
						}
					}
					else
					{
						this->m_header.next = NULL;
						this->m_header.pre = NULL;
						this->m_current = NULL;
					}
				}
				else
				{
					ret = false;
				}

			}
			else
			{
				ret = DualLinkList<T>::remove(i);
			}

			return ret;
		}

		virtual bool set(int i, const T& e)
		{
			return DualLinkList<T>::set(mod(i), e);
		}

		virtual bool get(int i, T& e) const
		{
			return DualLinkList<T>::get(mod(i), e);
		}

		virtual T get(int i) const
		{
			return DualLinkList<T>::get(mod(i));
		}

		virtual T& operator [] (int i)
		{
			return this->position(mod(i))->next->value;
		}

		virtual T operator [] (int i) const
		{
			return const_cast<DualCircleListV2<T>&>(*this)[i];
		}

		virtual int find(const T& e) const
		{
			int ret = -1;

			Node* slider = this->position(0)->next;

			for (int i = 0; i < this->m_length; i++)
			{
				if (slider->value == e)
				{
					ret = i;
					break;
				}
				slider = slider->next;
			}

			return ret;
		}

		virtual void clear()
		{
			while (this->m_length > 1)
			{
				remove(1);
			}

			if (this->m_length == 1)
			{
				Node* toDel = this->position(0)->next;

				this->m_header.next = NULL;
				this->m_header.pre = NULL;
				this->m_current = NULL;
				this->m_length = 0;

				this->destory(toDel);
			}
		}

		virtual bool move(int i, int step = 1)
		{
			return DualLinkList<T>::move(mod(i), step);
		}

		~DualCircleListV2()
		{
			clear();
		}
	};
}



#endif